

#ifndef UD_DBDIM_H
#define UD_DBDIM_H

#include "zdbmain.h"
#include "zdbmtext.h"
#include "zacgi.h"

#pragma pack(push, 8)

namespace UcDmUtil
{

    int dimfit  (int dimatfit, int dimtmove);
    int dimunit (int dimlunit, int dimfrac );

    int dimatfit(int dimfit);
    int dimtmove(int dimfit);
    int dimlunit(int dimunit);
    int dimfrac (int dimunit);

    const ZTCHAR * globalArrowName(const ZTCHAR * pName);
    const ZTCHAR * globalArrowName(UcDbObjectId blockId);

    const ZTCHAR * arrowName(const ZTCHAR * pName);
    const ZTCHAR * arrowName(UcDbObjectId blockId);

    bool isBuiltInArrow(const ZTCHAR * pName);

    bool isZeroLengthArrow(const ZTCHAR * pName);

    Ucad::ErrorStatus findArrowId(const ZTCHAR * pName,
                                        UcDbObjectId& blockId, 
                                        UcDbDatabase* pDb = 0);

    Ucad::ErrorStatus getArrowId(const ZTCHAR * pName,
                                        UcDbObjectId& blockId, 
                                        UcDbDatabase* pDb = 0);
};

class ZSOFT_NO_VTABLE UcDbDimension: public UcDbEntity
{
protected:
    UcDbDimension();
public:
    ~UcDbDimension();
    UCDB_DECLARE_MEMBERS(UcDbDimension);

    UcGePoint3d         textPosition() const;
    Ucad::ErrorStatus   setTextPosition(const UcGePoint3d&);

    ZSoft::Boolean      isUsingDefaultTextPosition() const;
    Ucad::ErrorStatus   useSetTextPosition();
    Ucad::ErrorStatus   useDefaultTextPosition();

    UcGeVector3d        normal() const;
    Ucad::ErrorStatus   setNormal(const UcGeVector3d&);

    virtual ZSoft::Boolean    isPlanar() const { return true; }
    virtual Ucad::ErrorStatus getPlane(UcGePlane&, UcDb::Planarity&) const;

    double              elevation() const;
    Ucad::ErrorStatus   setElevation(double);

    ZTCHAR *             dimensionText() const;
    Ucad::ErrorStatus   setDimensionText(const ZTCHAR *);

    double              textRotation() const;
    Ucad::ErrorStatus   setTextRotation(double);

    UcDbObjectId        dimensionStyle() const;
    Ucad::ErrorStatus   setDimensionStyle(UcDbObjectId);

    UcDbMText::AttachmentPoint textAttachment() const;
    Ucad::ErrorStatus   setTextAttachment(UcDbMText::AttachmentPoint eAtt);

    UcDb::LineSpacingStyle textLineSpacingStyle() const;
    Ucad::ErrorStatus   setTextLineSpacingStyle(UcDb::LineSpacingStyle eStyle);

    double              textLineSpacingFactor() const;
    Ucad::ErrorStatus   setTextLineSpacingFactor(double dFactor);

    Ucad::ErrorStatus   getDimstyleData(UcDbDimStyleTableRecord*& pRecord) const;
    Ucad::ErrorStatus   setDimstyleData(UcDbDimStyleTableRecord* pNewData);
    Ucad::ErrorStatus   setDimstyleData(UcDbObjectId newDataId);

    virtual void        erased(UcDbObject* dbObj, ZSoft::Boolean bErasing);

    virtual void        objectClosed(const UcDbObjectId dbObj);
	virtual void        dragStatus(const UcDb::DragStat status);

    double              horizontalRotation() const;
    Ucad::ErrorStatus   setHorizontalRotation(double newVal);

    UcDbObjectId        dimBlockId() const;
    Ucad::ErrorStatus   setDimBlockId(const UcDbObjectId&);
    UcGePoint3d         dimBlockPosition() const;
    Ucad::ErrorStatus   setDimBlockPosition(const UcGePoint3d&);
    Ucad::ErrorStatus   recomputeDimBlock(bool forceUpdate = true);
    Ucad::ErrorStatus   generateLayout();
    Ucad::ErrorStatus   measurement(double &val);
    Ucad::ErrorStatus   formatMeasurement(ZTCHAR *MTextContentBuffer,
										  const size_t contentBufferLen,
                                          double measurement,
                                          ZTCHAR *dimensionText);
	Ucad::ErrorStatus	formatMeasurement(ZTCHAR *MTextContentBuffer,
                                          double measurement,
                                          ZTCHAR *dimensionText);//Deprecated: will be removed in future.
    bool                isDynamicDimension() const;
    Ucad::ErrorStatus   setDynamicDimension(bool newVal);
    Ucad::ErrorStatus getOsnapPointsAtSubentPath(UcDb::OsnapMode osnapMode,
                                     const UcDbFullSubentPath& subentId,
                                     const UcGePoint3d&  pickPoint,
                                     const UcGePoint3d&  lastPoint,
                                     const UcGeMatrix3d& viewXform,
                                     UcGePoint3dArray&   snapPoints,
                                     UcDbIntArray&   geomIds) const;


    UcDbObjectId dimLineLinetype() const;
    Ucad::ErrorStatus setDimLineLinetype(const UcDbObjectId linetype);
    UcDbObjectId dimExt1Linetype() const;
    Ucad::ErrorStatus setDimExt1Linetype(const UcDbObjectId linetype);
    UcDbObjectId dimExt2Linetype() const;
    Ucad::ErrorStatus setDimExt2Linetype(const UcDbObjectId linetype);

    Ucad::ErrorStatus   removeTextField();
    Ucad::ErrorStatus   fieldToMText(UcDbMText* pDimMText);
    Ucad::ErrorStatus   fieldFromMText(UcDbMText* pDimMText);

    #undef UDBDIMVAR_H                   
    #include "zdbdimvar.h"

    int dimfit() const;
    int dimunit() const;

    Ucad::ErrorStatus setDimfit (int );
    Ucad::ErrorStatus setDimunit(int );
    bool                isHorizontalRefTextRotation() const;
    Ucad::ErrorStatus   setHorizontalRefTextRotation(bool newVal);
    bool getArrowFirstIsFlipped() const;
    bool getArrowSecondIsFlipped() const;
    Ucad::ErrorStatus setArrowFirstIsFlipped(bool bIsFlipped);
    Ucad::ErrorStatus setArrowSecondIsFlipped(bool bIsFlipped);

    virtual bool castShadows() const;
    virtual void setCastShadows(bool newVal);
    virtual bool receiveShadows() const;
    virtual void setReceiveShadows(bool newVal);

    UcGeMatrix3d blockTransform() const;
	enum DimInspect {
		kShapeRemove  = 0,     
		kShapeRound   = 1,     
		kShapeAngular = 2,     
		kShapeNone    = 4,     
		kShapeLabel   = 0x10,  
		kShapeRate    = 0x20,  
	};

	bool 				inspection() const;
	Ucad::ErrorStatus 	setInspection(bool val);

	int 				inspectionFrame() const;
	Ucad::ErrorStatus 	setInspectionFrame(int frame);

	const ZTCHAR* 		inspectionLabel() const;
	Ucad::ErrorStatus 	setInspectionLabel(const ZTCHAR* label);

	const ZTCHAR* 		inspectionRate() const;
	Ucad::ErrorStatus 	setInspectionRate(const ZTCHAR* label);
	
};

class UcDbOrdinateDimension: public UcDbDimension
{
public:
    UcDbOrdinateDimension();
    UcDbOrdinateDimension(
        ZSoft::Boolean     useXAxis,
        const UcGePoint3d& definingPoint,
        const UcGePoint3d& leaderEndPoint,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle  = UcDbObjectId::kNull);
    ~UcDbOrdinateDimension();
    UCDB_DECLARE_MEMBERS(UcDbOrdinateDimension);

    ZSoft::Boolean      isUsingXAxis() const;
    ZSoft::Boolean      isUsingYAxis() const;
    Ucad::ErrorStatus   useXAxis();
    Ucad::ErrorStatus   useYAxis();

    UcGePoint3d         origin() const;
    Ucad::ErrorStatus   setOrigin(const UcGePoint3d&);

    UcGePoint3d         definingPoint() const;
    Ucad::ErrorStatus   setDefiningPoint(const UcGePoint3d&);

    UcGePoint3d         leaderEndPoint() const;
    Ucad::ErrorStatus   setLeaderEndPoint(const UcGePoint3d&);

    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
};

class UcDbAlignedDimension: public UcDbDimension
{
public:
    UcDbAlignedDimension();
    UcDbAlignedDimension(
        const UcGePoint3d& xLine1Point,
        const UcGePoint3d& xLine2Point,
        const UcGePoint3d& dimLinePoint,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDbAlignedDimension();
    UCDB_DECLARE_MEMBERS(UcDbAlignedDimension);

    UcGePoint3d         xLine1Point() const;
    Ucad::ErrorStatus   setXLine1Point(const UcGePoint3d&);

    UcGePoint3d         xLine2Point() const;
    Ucad::ErrorStatus   setXLine2Point(const UcGePoint3d&);

    UcGePoint3d         dimLinePoint() const;
    Ucad::ErrorStatus   setDimLinePoint(const UcGePoint3d&);

    double              oblique() const;
    Ucad::ErrorStatus   setOblique(double);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
	bool 				jogSymbolOn() const;
	Ucad::ErrorStatus 	setJogSymbolOn(bool value);

	UcGePoint3d 		jogSymbolPosition() const;
	Ucad::ErrorStatus 	setJogSymbolPosition(const UcGePoint3d& pt);
};

class UcDbRotatedDimension: public UcDbDimension
{
public:
    UcDbRotatedDimension();
    UcDbRotatedDimension(
        double             rotation,
        const UcGePoint3d& xLine1Point,
        const UcGePoint3d& xLine2Point,
        const UcGePoint3d& dimLinePoint,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDbRotatedDimension();
    UCDB_DECLARE_MEMBERS(UcDbRotatedDimension);

    UcGePoint3d         xLine1Point() const;
    Ucad::ErrorStatus   setXLine1Point(const UcGePoint3d&);

    UcGePoint3d         xLine2Point() const;
    Ucad::ErrorStatus   setXLine2Point(const UcGePoint3d&);

    UcGePoint3d         dimLinePoint() const;
    Ucad::ErrorStatus   setDimLinePoint(const UcGePoint3d&);

    double              oblique() const;
    Ucad::ErrorStatus   setOblique(double);

    double              rotation() const;
    Ucad::ErrorStatus   setRotation(double);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
	bool 				jogSymbolOn() const;
	Ucad::ErrorStatus 	setJogSymbolOn(bool value);

	UcGePoint3d 		jogSymbolPosition() const;
	Ucad::ErrorStatus 	setJogSymbolPosition(const UcGePoint3d& pt);
};

class UcDb3PointAngularDimension: public UcDbDimension
{
public:
    UcDb3PointAngularDimension();
    UcDb3PointAngularDimension(
        const UcGePoint3d& centerPoint,
        const UcGePoint3d& xLine1Point,
        const UcGePoint3d& xLine2Point,
        const UcGePoint3d& arcPoint,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDb3PointAngularDimension();
    UCDB_DECLARE_MEMBERS(UcDb3PointAngularDimension);

    UcGePoint3d         arcPoint() const;
    Ucad::ErrorStatus   setArcPoint(const UcGePoint3d&);

    UcGePoint3d         xLine1Point() const;
    Ucad::ErrorStatus   setXLine1Point(const UcGePoint3d&);

    UcGePoint3d         xLine2Point() const;
    Ucad::ErrorStatus   setXLine2Point(const UcGePoint3d&);

    UcGePoint3d         centerPoint() const;
    Ucad::ErrorStatus   setCenterPoint(const UcGePoint3d&);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
	bool 				extArcOn() const;
	Ucad::ErrorStatus 	setExtArcOn(bool value);
};

class UcDb2LineAngularDimension: public UcDbDimension
{
public:
    UcDb2LineAngularDimension();
    UcDb2LineAngularDimension(
        const UcGePoint3d& xLine1Start,
        const UcGePoint3d& xLine1End,
        const UcGePoint3d& xLine2Start,
        const UcGePoint3d& xLine2End,
        const UcGePoint3d& arcPoint,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDb2LineAngularDimension();
    UCDB_DECLARE_MEMBERS(UcDb2LineAngularDimension);

    UcGePoint3d         arcPoint() const;
    Ucad::ErrorStatus   setArcPoint(const UcGePoint3d&);

    UcGePoint3d         xLine1Start() const;
    Ucad::ErrorStatus   setXLine1Start(const UcGePoint3d&);

    UcGePoint3d         xLine1End() const;
    Ucad::ErrorStatus   setXLine1End(const UcGePoint3d&);

    UcGePoint3d         xLine2Start() const;
    Ucad::ErrorStatus   setXLine2Start(const UcGePoint3d&);

    UcGePoint3d         xLine2End() const;
    Ucad::ErrorStatus   setXLine2End(const UcGePoint3d&);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
	bool 				extArcOn() const;
	Ucad::ErrorStatus 	setExtArcOn(bool value);
};

class UcDbRadialDimension: public UcDbDimension
{
public:
    UcDbRadialDimension();
    UcDbRadialDimension(
        const UcGePoint3d& center,
        const UcGePoint3d& chordPoint,
        double             leaderLength,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDbRadialDimension();
    UCDB_DECLARE_MEMBERS(UcDbRadialDimension);

    double              leaderLength() const;
    Ucad::ErrorStatus   setLeaderLength(double);

    UcGePoint3d         center() const;
    Ucad::ErrorStatus   setCenter(const UcGePoint3d&);

    UcGePoint3d         chordPoint() const;
    Ucad::ErrorStatus   setChordPoint(const UcGePoint3d&);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
    double extArcStartAngle() const;
    Ucad::ErrorStatus setExtArcStartAngle(double newAngle);

    double extArcEndAngle() const;
    Ucad::ErrorStatus setExtArcEndAngle(double newAngle);
};

class UcDbDiametricDimension: public UcDbDimension
{
public:
    UcDbDiametricDimension();
    UcDbDiametricDimension(
        const UcGePoint3d& chordPoint,
        const UcGePoint3d& farChordPoint,
        double             leaderLength,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);
    ~UcDbDiametricDimension();
    UCDB_DECLARE_MEMBERS(UcDbDiametricDimension);

    double              leaderLength() const;
    Ucad::ErrorStatus   setLeaderLength(double);

    UcGePoint3d         chordPoint() const;
    Ucad::ErrorStatus   setChordPoint(const UcGePoint3d&);

    UcGePoint3d         farChordPoint() const;
    Ucad::ErrorStatus   setFarChordPoint(const UcGePoint3d&);
    virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
	double 				extArcStartAngle() const;
	Ucad::ErrorStatus 	setExtArcStartAngle(double newAngle);

	double 				extArcEndAngle() const;
	Ucad::ErrorStatus 	setExtArcEndAngle(double newAngle);
};

class UcDbArcDimension: public UcDbDimension
{
public:
    UcDbArcDimension();

    UcDbArcDimension(
        const UcGePoint3d& centerPoint,
        const UcGePoint3d& xLine1Point,
        const UcGePoint3d& xLine2Point,
        const UcGePoint3d& arcPoint,
        const ZTCHAR * dimText = NULL,
        UcDbObjectId dimStyle = UcDbObjectId::kNull);

	~UcDbArcDimension();
	UCDB_DECLARE_MEMBERS(UcDbArcDimension);

	UcGePoint3d         arcPoint() const;
	Ucad::ErrorStatus	setArcPoint(const UcGePoint3d & arcPt);

	UcGePoint3d         xLine1Point() const;
	Ucad::ErrorStatus   setXLine1Point(const UcGePoint3d & xLine1Pt);

	UcGePoint3d         xLine2Point() const;
	Ucad::ErrorStatus   setXLine2Point(const UcGePoint3d & xLine2Pt);

	UcGePoint3d         centerPoint() const;
	Ucad::ErrorStatus   setCenterPoint(const UcGePoint3d & ctrPt);

	bool                isPartial() const;
	Ucad::ErrorStatus   setIsPartial(const bool & partial);

	double              arcStartParam() const;
	Ucad::ErrorStatus   setArcStartParam(const double & arcParam);

	double              arcEndParam() const;
	Ucad::ErrorStatus   setArcEndParam(const double & arcParam);

	bool                hasLeader() const;
	Ucad::ErrorStatus   setHasLeader(const bool & leaderVal);

	UcGePoint3d         leader1Point() const;       
	Ucad::ErrorStatus   setLeader1Point(const UcGePoint3d & ldr1Pt);

	UcGePoint3d         leader2Point() const;   
	Ucad::ErrorStatus   setLeader2Point(const UcGePoint3d & ldr2Pt);

	int					arcSymbolType() const;
	Ucad::ErrorStatus	setArcSymbolType(const int symbol);
	virtual Ucad::ErrorStatus   getClassID(CLSID* pClsid) const;
};

class UcDbRadialDimensionLarge: public UcDbDimension
{
public:

	UcDbRadialDimensionLarge();

    UcDbRadialDimensionLarge(
        const UcGePoint3d& center,
        const UcGePoint3d& chordPoint,
        const UcGePoint3d& overrideCenter,
        const UcGePoint3d& jogPoint,
        double             jogAngle,
        const ZTCHAR *      dimText = NULL,
        UcDbObjectId       dimStyle = UcDbObjectId::kNull);

	~UcDbRadialDimensionLarge();
	UCDB_DECLARE_MEMBERS(UcDbRadialDimensionLarge);

	UcGePoint3d         center() const;
	Ucad::ErrorStatus	setCenter(const UcGePoint3d & centerPoint);

	UcGePoint3d         chordPoint() const;
	Ucad::ErrorStatus	setChordPoint(const UcGePoint3d & chordPoint);

	UcGePoint3d         overrideCenter() const;
	Ucad::ErrorStatus	setOverrideCenter(const UcGePoint3d & overrideCenterPoint);

	UcGePoint3d         jogPoint() const;
	Ucad::ErrorStatus	setJogPoint(const UcGePoint3d & jogPoint);

	double              jogAngle() const;
	Ucad::ErrorStatus	setJogAngle(double jogAngle);
    Ucad::ErrorStatus   setOverrideCenterPP(const UcGePoint3d & overrideCenterPointPP);
    Ucad::ErrorStatus   setJogPointPP(const UcGePoint3d & jogPointPP);
    Ucad::ErrorStatus   setTextPositionPP(const UcGePoint3d & textPointPP);
    virtual Ucad::ErrorStatus   getClassID(CLSID * pClsid) const;
	double				extArcStartAngle() const;
    Ucad::ErrorStatus setExtArcStartAngle(double newAngle);

	double				extArcEndAngle() const;
    Ucad::ErrorStatus setExtArcEndAngle(double newAngle);
};

#pragma pack(pop)

#endif
